#!/usr/bin/env python
"""
Acorn-SDR ('A Collection of Radio Nodes')
(c) Bob Cowdery (G3UKB) 2009

File: instr.py
Date: January 2009

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

The author can be reached by email at

bob@g3ukb.co.uk

================================================================================
Module Description:

Input streaming.

"""

#-------------------------------------------------------------------------------
# System imports
import sys, time, traceback
from Numeric import *
import jack

#===============================================================================
class AudioIn():
    
    #---------------------------------------------------------------------------
    def __init__(self, ch1, ch2, frames):
        self.ch1 = ch1
        self.ch2 = ch2
        self.frames = frames
        self.capture = zeros((2,self.frames), 'f')
        self.out = zeros((2,self.frames), 'f')
        self.capture_on = False
        
    #---------------------------------------------------------------------------
    def stream_on(self):
        jack.attach("acornin")
        jack.register_port("in_1", jack.IsInput)
        jack.register_port("in_2", jack.IsInput)
        jack.register_port("out_1", jack.IsOutput)
        jack.register_port("out_2", jack.IsOutput)
        jack.activate()
        jack.connect(self.ch1, "acornin:in_1")
        jack.connect(self.ch2, "acornin:in_2")
        self.capture_on = True

    #---------------------------------------------------------------------------
    def stream_off(self):
        if self.capture_on == True:
            jack.disconnect(self.ch1, "acornin:in_1")
            jack.disconnect(self.ch2, "acornin:in_2")
            jack.deactivate()
            jack.detach()
            self.capture_on = False
    
    #---------------------------------------------------------------------------
    def capture_audio(self):
        
        if not self.capture_on: return None
        
        zerodata = arange(0.0, self.frames, 1.0).tolist()
        try:
            # Exchange the streams
            jack.process(self.out, self.capture)
            #self.out = self.capture.copy()
            #print self.out
            #return self.capture.tolist()
            #stream.data(payload)
        except jack.InputSyncError:
            print "Jack - Input Sync Error"
            pass
        except jack.OutputSyncError:
            print "Jack - Output Sync Error"
            pass
        return self.capture.tolist()

    #-----------------------------------------------------------------------
    def set_audioframes(self, value):
        self.updates['audio_frames'] = (value, self.set_audioframes_1, True)
        
    #-----------------------------------------------------------------------
    def set_audioframes_1(self, value):
        self.frames = value
        
    #-----------------------------------------------------------------------
    def apply_updates(self):
        # This must be called at the end of a cycle so we don't apply updates
        # when the outstr is running
        # Let this run straight away as we will match any stray buffers in the pipeline
        # by sending an empty response of the correct size
        # ToDo: We should have a mutex around here as there is a window
        for key in self.updates.keys():
            if self.updates[key][2]:
                was_on = False
                if self.capture_on:
                    was_on = True
                    self.stream_off()
            self.updates[key][1](self.updates[key][0])
            # Reinitialise
            if self.updates[key][2]:
                if was_on:
                    self.stream_on()                    
        self.updates.clear()